// store/ws.ts
import { computed, ref } from 'vue';

import { useAccessStore } from '@vben/stores';

// store/ws.ts
import { defineStore } from 'pinia';

class WebSocketManager {
  /**
   * 是否已连接
   */
  get connected(): boolean {
    return this.isConnected;
  }
  /**
   * 获取连接状态
   */
  get status(): null | number {
    return this.ws ? this.ws.readyState : null;
  }
  // 健康检测相关属性
  private heartbeatInterval: any = null;
  private heartbeatTimer: number = 30_000; // 30秒发送一次心跳
  private isConnected: boolean = false;

  private messageCallback: ((data: any) => void) | null = null;

  private reconnectInterval: number = 5000;

  private reconnectTimer: any = null;
  private url: string;
  private ws: null | WebSocket = null;

  constructor(url: string) {
    this.url = url;
  }

  /**
   * 建立WebSocket连接
   */
  connect(): void {
    try {
      const accessStore = useAccessStore();
      if (!accessStore.accessToken) return;

      // 使用token作为子协议
      this.ws = new WebSocket(this.url, [accessStore.accessToken]);

      this.ws.addEventListener('open', () => {
        // eslint-disable-next-line no-console
        console.log('WebSocket连接已建立');
        this.isConnected = true;
        this.clearReconnectTimer();

        // 连接成功后启动心跳检测
        this.startHeartbeat();
      });

      // eslint-disable-next-line unicorn/prefer-add-event-listener
      this.ws.onmessage = (event) => {
        // eslint-disable-next-line no-console
        console.log('收到消息:', event.data);
        try {
          const data = JSON.parse(event.data);

          // 处理心跳响应
          if (data.type === 'health') {
            // eslint-disable-next-line no-console
            console.log('收到心跳响应');
          }

          if (this.messageCallback) {
            this.messageCallback(data);
          }
        } catch (error) {
          console.error('解析消息失败:', error);
        }
      };

      this.ws.addEventListener('close', () => {
        // eslint-disable-next-line no-console
        console.log('WebSocket连接已关闭');
        this.isConnected = false;
        this.stopHeartbeat(); // 连接关闭时停止心跳
        this.attemptReconnect();
      });

      // eslint-disable-next-line unicorn/prefer-add-event-listener
      this.ws.onerror = (error) => {
        console.error('WebSocket发生错误:', error);
        this.isConnected = false;
        this.stopHeartbeat(); // 错误时停止心跳
      };
    } catch (error) {
      console.error('创建WebSocket连接失败:', error);
      this.attemptReconnect();
    }
  }

  /**
   * 关闭连接
   */
  disconnect(): void {
    this.stopHeartbeat(); // 停止心跳
    this.clearReconnectTimer();
    if (this.ws) {
      this.ws.close();
      this.ws = null;
    }
    this.isConnected = false;
  }

  /**
   * 设置消息回调
   * @param callback 消息处理回调函数
   */
  onMessage(callback: (data: any) => void): void {
    this.messageCallback = callback;
  }

  /**
   * 发送消息
   * @param data 要发送的数据
   */
  send(data: any): boolean {
    if (this.isConnected && this.ws && this.ws.readyState === WebSocket.OPEN) {
      try {
        const message = typeof data === 'string' ? data : JSON.stringify(data);
        this.ws.send(message);
        return true;
      } catch (error) {
        console.error('发送消息失败:', error);
        return false;
      }
    } else {
      console.warn('WebSocket未连接，无法发送消息');
      return false;
    }
  }

  /**
   * 尝试重连
   */
  private attemptReconnect(): void {
    this.clearReconnectTimer();
    this.reconnectTimer = setTimeout(() => {
      // eslint-disable-next-line no-console
      console.log('尝试重新连接...');
      this.connect();
    }, this.reconnectInterval);
  }

  /**
   * 清除重连定时器
   */
  private clearReconnectTimer(): void {
    if (this.reconnectTimer) {
      clearTimeout(this.reconnectTimer);
      this.reconnectTimer = null;
    }
  }

  /**
   * 处理连接丢失
   */
  private handleConnectionLost(): void {
    // eslint-disable-next-line no-console
    console.log('检测到连接丢失，尝试重连...');
    this.disconnect();
    this.attemptReconnect();
  }

  /**
   * 启动心跳检测
   */
  private startHeartbeat(): void {
    if (this.heartbeatInterval) {
      clearInterval(this.heartbeatInterval);
    }

    this.heartbeatInterval = setInterval(() => {
      if (
        this.isConnected &&
        this.ws &&
        this.ws.readyState === WebSocket.OPEN
      ) {
        try {
          this.ws.send(
            JSON.stringify({ type: 'health', timestamp: Date.now() }),
          );
        } catch (error) {
          console.error('发送心跳失败:', error);
          this.handleConnectionLost();
        }
      }
    }, this.heartbeatTimer);
  }

  /**
   * 停止心跳检测
   */
  private stopHeartbeat(): void {
    if (this.heartbeatInterval) {
      clearInterval(this.heartbeatInterval);
      this.heartbeatInterval = null;
    }
  }
}

// 创建Pinia Store
export const useWebsocketStore = defineStore('websocket', () => {
  const wsManager = new WebSocketManager('ws://localhost:18080/ws');
  const messages = ref<any[]>([]);
  const isConnected = computed(() => wsManager.connected);

  // 初始化WebSocket连接
  const initWebsocket = () => {
    wsManager.onMessage((data) => {
      messages.value.push(data);
      // 可以在这里触发其他业务逻辑
    });
  };

  // 建立连接
  const connect = () => {
    if (!wsManager.connected) {
      wsManager.connect();
    }
  };

  // 断开连接
  const disconnect = () => {
    wsManager.disconnect();
  };

  // 发送消息
  const sendMessage = (data: any) => {
    return wsManager.send(data);
  };

  // 获取连接状态
  const getConnectionStatus = () => {
    const status = wsManager.status;
    switch (status) {
      case WebSocket.CLOSED: {
        return '已关闭';
      }
      case WebSocket.CLOSING: {
        return '关闭中';
      }
      case WebSocket.CONNECTING: {
        return '连接中';
      }
      case WebSocket.OPEN: {
        return '已连接';
      }
      default: {
        return '未知状态';
      }
    }
  };

  return {
    // 状态
    isConnected,
    messages,

    // 方法
    initWebsocket,
    connect,
    disconnect,
    sendMessage,
    getConnectionStatus,
  };
});

// 导出WebSocketManager类以供直接使用
export { WebSocketManager };
